#ifndef LIST_H_
#define LIST_H_
#include <stddef.h>
#define esmd_list(type)             \
  struct {                          \
    typeof(type) *v;                \
    unsigned long max_cnt, cur_cnt; \
  }
#define ESMD_LIST_GROW_RATE 1.5

typedef esmd_list(void) esmd_list_void;

#define ELIST_ES(list_ptr) (sizeof(*(list_ptr)->v))
#define ELIST_PT(list_ptr) (typeof((list_ptr)->v))
#define esmd_list_get_slot(list_ptr) (ELIST_PT(list_ptr) esmd_list_get_slot_impl((esmd_list_void *)(list_ptr), ELIST_ES(list_ptr)))
#define esmd_list_get(list_ptr, idx) (ELIST_PT(list_ptr) esmd_list_get_impl((esmd_list_void *)(list_ptr), idx, ELIST_ES(list_ptr)))
#define esmd_list_init(list_ptr, max_cnt, name) esmd_list_init_impl((esmd_list_void *)(list_ptr), max_cnt, ELIST_ES(list_ptr), name)
#define esmd_list_destroy(list_ptr) esmd_list_destroy_impl((esmd_list_void *)(list_ptr))
#define LIST_FOREACH(var, list_ptr) for (typeof((list_ptr)->v) var = (list_ptr)->v; v < (list_ptr)->v + (list_ptr)->cur_cnt; var++)
#define ARR_FOR(var, arr, cnt) for (typeof(arr) var = arr; var < ((arr) + (cnt)); var++)
//function signatures
void esmd_list_init_impl(esmd_list_void *list, unsigned long max_cnt, size_t elem_size, const char *name) ;
void esmd_list_ensure_cnt(esmd_list_void *list, unsigned long cnt, size_t elem_size) ;
void *esmd_list_get_slot_impl(esmd_list_void *list, size_t elem_size) ;
void *esmd_list_get_impl(esmd_list_void *list, unsigned long idx, size_t elem_size) ;
void esmd_list_destroy_impl(esmd_list_void *list) ;
//end function signatures
#endif
